package de.sabram.upb.specs.serializer;

import com.google.inject.Inject;
import com.google.inject.Provider;
import de.sabram.upb.specs.con.ALT;
import de.sabram.upb.specs.con.ConPackage;
import de.sabram.upb.specs.con.ConSpec;
import de.sabram.upb.specs.con.ElemList;
import de.sabram.upb.specs.con.Literal;
import de.sabram.upb.specs.con.NonTerminal;
import de.sabram.upb.specs.con.Reference;
import de.sabram.upb.specs.con.Rule;
import de.sabram.upb.specs.services.ConGrammarAccess;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.serializer.acceptor.ISemanticSequenceAcceptor;
import org.eclipse.xtext.serializer.acceptor.SequenceFeeder;
import org.eclipse.xtext.serializer.diagnostic.ISemanticSequencerDiagnosticProvider;
import org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic.Acceptor;
import org.eclipse.xtext.serializer.sequencer.AbstractDelegatingSemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.GenericSequencer;
import org.eclipse.xtext.serializer.sequencer.ISemanticNodeProvider.INodesForEObjectProvider;
import org.eclipse.xtext.serializer.sequencer.ISemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient;

@SuppressWarnings("all")
public class ConSemanticSequencer extends AbstractDelegatingSemanticSequencer {

	@Inject
	private ConGrammarAccess grammarAccess;
	
	public void createSequence(EObject context, EObject semanticObject) {
		if(semanticObject.eClass().getEPackage() == ConPackage.eINSTANCE) switch(semanticObject.eClass().getClassifierID()) {
			case ConPackage.ALT:
				if(context == grammarAccess.getALTRule()) {
					sequence_ALT(context, (ALT) semanticObject); 
					return; 
				}
				else if(context == grammarAccess.getRHSRule()) {
					sequence_ALT_RHS(context, (ALT) semanticObject); 
					return; 
				}
				else break;
			case ConPackage.CON_SPEC:
				if(context == grammarAccess.getConSpecRule()) {
					sequence_ConSpec(context, (ConSpec) semanticObject); 
					return; 
				}
				else break;
			case ConPackage.ELEM_LIST:
				if(context == grammarAccess.getElemListRule()) {
					sequence_ElemList(context, (ElemList) semanticObject); 
					return; 
				}
				else break;
			case ConPackage.LITERAL:
				if(context == grammarAccess.getLiteralRule() ||
				   context == grammarAccess.getTerminalOrLiteralRule()) {
					sequence_Literal(context, (Literal) semanticObject); 
					return; 
				}
				else break;
			case ConPackage.NON_TERMINAL:
				if(context == grammarAccess.getNonTerminalRule()) {
					sequence_NonTerminal(context, (NonTerminal) semanticObject); 
					return; 
				}
				else break;
			case ConPackage.REFERENCE:
				if(context == grammarAccess.getReferenceRule() ||
				   context == grammarAccess.getTerminalOrLiteralRule()) {
					sequence_Reference(context, (Reference) semanticObject); 
					return; 
				}
				else break;
			case ConPackage.RULE:
				if(context == grammarAccess.getRuleRule()) {
					sequence_Rule(context, (Rule) semanticObject); 
					return; 
				}
				else break;
			}
		if (errorAcceptor != null) errorAcceptor.accept(diagnosticProvider.createInvalidContextOrTypeDiagnostic(semanticObject, context));
	}
	
	/**
	 * Constraint:
	 *     (elementList+=ElemList elementList+=ElemList*)
	 */
	protected void sequence_ALT(EObject context, ALT semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (elementList+=ElemList elementList+=ElemList* terminalOrLiteral+=TerminalOrLiteral*)
	 */
	protected void sequence_ALT_RHS(EObject context, ALT semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     rules+=Rule*
	 */
	protected void sequence_ConSpec(EObject context, ConSpec semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     ((terminalOrLiteral+=TerminalOrLiteral | rhs+=RHS | rhs+=RHS)? | terminalOrLiteral+=TerminalOrLiteral)*
	 */
	protected void sequence_ElemList(EObject context, ElemList semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     ref=STRING
	 */
	protected void sequence_Literal(EObject context, Literal semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ConPackage.Literals.LITERAL__REF) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ConPackage.Literals.LITERAL__REF));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getLiteralAccess().getRefSTRINGTerminalRuleCall_0(), semanticObject.getRef());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     name=ID
	 */
	protected void sequence_NonTerminal(EObject context, NonTerminal semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ConPackage.Literals.NON_TERMINAL__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ConPackage.Literals.NON_TERMINAL__NAME));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getNonTerminalAccess().getNameIDTerminalRuleCall_0(), semanticObject.getName());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     ref=[TokenName|ID]
	 */
	protected void sequence_Reference(EObject context, Reference semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ConPackage.Literals.REFERENCE__REF) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ConPackage.Literals.REFERENCE__REF));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getReferenceAccess().getRefTokenNameIDTerminalRuleCall_0_1(), semanticObject.getRef());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (nonTerminal=NonTerminal rhs=RHS)
	 */
	protected void sequence_Rule(EObject context, Rule semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ConPackage.Literals.RULE__NON_TERMINAL) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ConPackage.Literals.RULE__NON_TERMINAL));
			if(transientValues.isValueTransient(semanticObject, ConPackage.Literals.RULE__RHS) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ConPackage.Literals.RULE__RHS));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getRuleAccess().getNonTerminalNonTerminalParserRuleCall_1_0(), semanticObject.getNonTerminal());
		feeder.accept(grammarAccess.getRuleAccess().getRhsRHSParserRuleCall_3_0(), semanticObject.getRhs());
		feeder.finish();
	}
}
